package com.zoho.aimei.utils;

import cn.hutool.http.HttpRequest;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.zoho.aimei.common.ZohoRecord;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;

import java.util.*;

@Slf4j
@Component
public class BooksApiUtil {

    final String orgId = "890684180"; // 组织id
    final String booksUrl = "https://www.zohoapis.com/books/v3/"; // 域名路径
    final String item_url = booksUrl + "items?organization_id=" + orgId; // item 路径
    final String contacts_url = booksUrl + "contacts?organization_id=" + orgId; // contacts 路径
    final String contacts_ByEmail_url = booksUrl + "contacts?organization_id=" + orgId + "&email="; // contacts 路径
    final String salesOrders_url = booksUrl + "salesorders?organization_id=" + orgId; // salesorders 路径
    ZohoRecord zohoRecord;

    public BooksApiUtil(ZohoRecord zohoRecord) {
        this.zohoRecord = zohoRecord;
    }

    /*
     *****************************************************           通用方法       *****************************************************
     */

    /**
     * 通用_获取 headMap
     */
    private Map<String, String> getHeadMap(String accessToken) {
        Map<String, String> map = new HashMap<>();
        map.put("Authorization", "Zoho-oauthtoken " + accessToken);
        return map;
    }

    /**
     * 通用_get请求
     */
    private JSONObject getRequest(String accessToken, String url) {
        return HttpUtil.getData(url, getHeadMap(accessToken));
    }

    /**
     * 通用_delete请求
     */
    private JSONObject delRequest(String accessToken, String url) {
        return HttpUtil.delData(url, getHeadMap(accessToken));
    }

    /**
     * 通用_使用分页方式，循环获取全量数据
     *
     * @param baseUrl   基础url，传入后，会自动拼接分页参数
     * @param arrayName 从接口返回中，获取数据的api名称,比如：data、user
     * @return 数据list
     */
    private List<JSONObject> whileGetDataByPage(String baseUrl, String arrayName) {
        Set<JSONObject> set = new HashSet<>();
        int page = 1;
        boolean flag;
        String failUrl = "";
        do {
            try {
                String url = baseUrl + "&page=" + page + "&per_page=200";
                failUrl = url;
                JSONObject record = getRequest(zohoRecord.getAccessToken(), url);
                if (Objects.isNull(record)) {
                    return new ArrayList<>();
                }
                JSONArray data = record.getJSONArray(arrayName);
                set.addAll(data.toJavaList(JSONObject.class));
                flag = record.getJSONObject("page_context").getBoolean("has_more_page");
                page++;
            } catch (Exception e) {
                log.error("failUrl = " + failUrl);
                e.printStackTrace();
                flag = false;
            }
        } while (flag);
        return new ArrayList<>(set);
    }


    /*
     *****************************************************           items  产品       *****************************************************
     */

    /**
     * 获取item产品列表数据
     */
    public List<JSONObject> getAllItemList() {
        return whileGetDataByPage(item_url, "items");
    }

    /**
     * 新增 单条 item产品数据
     */
    public String insertItemData(JSONObject itemData) {
        try {
            String result = HttpRequest.post(item_url).header("Authorization", "Zoho-oauthtoken " + zohoRecord.getAccessToken())
                    .header("Content-Type", "application/json").body(itemData.toJSONString()).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getInteger("code") != 0) {
                log.error("数据新增失败parameter={}", itemData.toJSONString());
                log.error("数据新增失败result={}", jsonObject.toJSONString());
            }
            String itemId = jsonObject.getJSONObject("item").getString("item_id");
            log.info("新增item成功，数据id=" + itemId);
            return itemId;
        } catch (Exception e) {
            log.error("数据新增失败parameter={}", itemData.toJSONString());
            log.error("数据新增失败result_exception={} ", e.getMessage());
        }
        return null;
    }

    /*
     *****************************************************           contacts 联系人      *****************************************************
     */

    /**
     * 获取 contacts 联系人列表数据
     * 该接口包含2个模块：customer、vendor。可以通过contact_type字段区分
     */
    public List<JSONObject> getAllContactsList() {
        return whileGetDataByPage(contacts_url, "contacts");
    }

    /**
     * 获取 contacts 联系人列表数据。通过邮件查询
     * 该接口包含2个模块：customer、vendor。可以通过contact_type字段区分
     */
    public List<JSONObject> getAllContactsListByEmail(String email) {
        return whileGetDataByPage(contacts_ByEmail_url + email, "contacts");
    }

    /**
     * 新增 单条 contacts
     */
    public String insertContactData(JSONObject contactData) {
        try {
            String result = HttpRequest.post(contacts_url).header("Authorization", "Zoho-oauthtoken " + zohoRecord.getAccessToken())
                    .header("Content-Type", "application/json").body(contactData.toJSONString()).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getInteger("code") != 0) {
                log.error("数据新增失败parameter={}", contactData.toJSONString());
                log.error("数据新增失败result={}", jsonObject.toJSONString());
            }

            String contactId = jsonObject.getJSONObject("contact").getString("contact_id");
            log.info("新增customer成功，数据id=" + contactId);
            return contactId;
        } catch (Exception e) {
            log.error("数据新增失败parameter={}", contactData.toJSONString());
            log.error("数据新增失败result_exception={} ", e.getMessage());
        }
        return null;
    }

    /**
     * 修改 单条 contacts。contact_name 必填
     */
    public String updateContactData(JSONObject contactData, String updateId) {
        try {
            String url = booksUrl + "contacts/" + updateId + "?organization_id=" + orgId;
            String result = HttpRequest.put(url).header("Authorization", "Zoho-oauthtoken " + zohoRecord.getAccessToken())
                    .header("Content-Type", "application/json").body(contactData.toJSONString()).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getInteger("code") != 0) {
                log.error("数据修改失败parameter={}", contactData.toJSONString());
                log.error("数据修改失败result={}", jsonObject.toJSONString());
            }

            String contactId = jsonObject.getJSONObject("contact").getString("contact_id");
            log.info("修改customer成功，数据id=" + contactId);
            return contactId;
        } catch (Exception e) {
            log.error("数据修改失败parameter={}", contactData.toJSONString());
            log.error("数据修改失败result_exception={} ", e.getMessage());
        }
        return null;
    }
    /*
     *****************************************************           salesOrders 销售订单      *****************************************************
     */

    /**
     * 获取 salesOrders 销售订单 列表数据
     */
    public List<JSONObject> getAllSalesOrdersList() {
        return whileGetDataByPage(salesOrders_url, "salesorders");
    }

    /**
     * 新增 单条 saleOrder
     */
    public String insertSaleOrderData(JSONObject saleOrderData) {
        try {
            String result = HttpRequest.post(salesOrders_url).header("Authorization", "Zoho-oauthtoken " + zohoRecord.getAccessToken())
                    .header("Content-Type", "application/json").body(saleOrderData.toJSONString()).execute().body();
            JSONObject jsonObject = JSONObject.parseObject(result);
            if (jsonObject.getInteger("code") != 0) {
                log.error("数据新增失败parameter={}", saleOrderData.toJSONString());
                log.error("数据新增失败result={}", jsonObject.toJSONString());
            }
            String saleOrderId = jsonObject.getJSONObject("salesorder").getString("salesorder_id");
            log.info("新增saleOrder成功，数据id=" + saleOrderId);
            return saleOrderId;
        } catch (Exception e) {
            log.error("数据新增失败parameter={}", saleOrderData.toJSONString());
            log.error("数据新增失败result_exception={} ", e.getMessage());
        }
        return null;
    }
}
